package yxy.game.pm2.bean;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.redisson.api.RMap;
import yxy.apple.util.RandomStringUtility;
import yxy.apple.util.RandomUtility;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.commandertally;
import yxy.cherry.data.bean.commandertallyrandom;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.game.pm2.bean.db.newDao.PickedTroopsSlotDAO;
import yxy.game.pm2.bean.db.po.PickedTroopsSlotPo;
import yxy.game.pm2.bean.module.BaseGameRedisLockBean;

import java.util.*;

import static yxy.apple.util.StringTrans.arrayList2String;
import static yxy.apple.util.StringTrans.string2ArrayList;

//兵符
public class PickedTroopsSlot extends BaseGameRedisLockBean {

    public static int maxNum = 100; //背包最大值

    // bean==========================================================================

    private String code;    //code
    private int dataId;     //兵符的id
    private int type;       //类型  : 哪个阵容
    private String name;    //名字
    private int quality;    //品质
    private ArrayList<Integer> entryId;  //词条的id
    private ArrayList<Integer> value;    //值
    private ArrayList<Integer> isLock;   //是否锁
    private Boolean isUse; //是否正在使用
    // 重铸
    private ArrayList<Integer> reEntryId;//重铸的词条id
    private ArrayList<Integer> reValue;//重置的词条id值


    public ArrayList<Integer> getIsLock() {
        return isLock;
    }

    public void setIsLock(ArrayList<Integer> isLock) {
        this.isLock = isLock;
    }

    public Boolean getUse() {
        return isUse;
    }

    public void setUse(Boolean use) {
        isUse = use;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public int getDataId() {
        return dataId;
    }

    public void setDataId(int dataId) {
        this.dataId = dataId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ArrayList<Integer> getEntryId() {
        return entryId;
    }

    public void setEntryId(ArrayList<Integer> entryId) {
        this.entryId = entryId;
    }

    public ArrayList<Integer> getValue() {
        return value;
    }

    public void setValue(ArrayList<Integer> value) {
        this.value = value;
    }

    public ArrayList<Integer> getReEntryId() {
        return reEntryId;
    }

    public void setReEntryId(ArrayList<Integer> reEntryId) {
        this.reEntryId = reEntryId;
    }

    public ArrayList<Integer> getReValue() {
        return reValue;
    }

    public void setReValue(ArrayList<Integer> reValue) {
        this.reValue = reValue;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public int getQuality() {
        return quality;
    }

    public void setQuality(int quality) {
        this.quality = quality;
    }

    // 方法==========================================================================

    /**
     * 重铸
     */
    public static PickedTroopsSlot recoin(String playerCode, PickedTroopsSlot slot, JSONArray idsList, commandertally data) {

        //获取词条的最高最低区域
        int min = data.getEntryminlevel();
        int max = data.getEntrymaxlevel();

        ArrayList<Integer> isLock = new ArrayList<>();
        ArrayList<Integer> reEntryId = new ArrayList<>();
        ArrayList<Integer> reEntryValue = new ArrayList<>();

        //jsonArray 随机的样本
        JSONArray jsonArray = new JSONArray();
        Map<String, commandertallyrandom> allData = DataCenter.getAllData(commandertallyrandom.class);
        for (commandertallyrandom value : allData.values()) {
            if (value.getEntrylevel() >= min && value.getEntrylevel() <= max) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id", value.getId());//对应技能id
                jsonObject.put("value", RandomUtility.nextInt(value.getMin(), value.getMax()));//随机的范围值
                jsonArray.add(jsonObject);
            }
        }

        //添加重铸的属性以及值
        for (int i = 0; i < slot.getEntryId().size(); i++) {
            Boolean isGone = true;

            //遍历传进来的id集合，进行锁操作
            for (int y = 0; y < idsList.size(); y++) {
                JSONObject jsonObject = idsList.getJSONObject(y);
                if (slot.getEntryId().get(i) == jsonObject.getInteger("id") && i == jsonObject.getInteger("index")) {
                    isLock.add(1);//锁住
                    reEntryId.add(slot.getEntryId().get(i));
                    reEntryValue.add(slot.getValue().get(i));
                    isGone = false;
                    break;
                }
            }

            if (isGone) {
                JSONObject jsonObject = jsonArray.getJSONObject(RandomUtility.nextInt(0, jsonArray.size() - 1));
                isLock.add(0);//不锁
                reEntryId.add(jsonObject.getIntValue("id"));
                reEntryValue.add(jsonObject.getIntValue("value"));
            }

        }

        slot.setReEntryId(reEntryId);
        slot.setReValue(reEntryValue);
        slot.setIsLock(isLock);
        PickedTroopsSlot.set(playerCode, slot);

        return slot;
    }


    /**
     * 随机code
     *
     * @return
     */
    static private String randomCode() {
        return String.format("ss%s", RandomStringUtility.randomLowerNumeric(4));
    }

    // redis==========================================================================
    private static String key(String playerCode) {
        return String.format("PLAYER:%s:MODULE:PICKEDTROOPSSLOT", playerCode);
    }

    static private RMap<String, PickedTroopsSlot> touch(String playerCode) throws RedisException {
        RMap<String, PickedTroopsSlot> rMap = RedisManager.client(redis()).getMap(key(playerCode));
        if (!rMap.isExists()) { //从db读
            List<PickedTroopsSlotPo> poList = PickedTroopsSlotDAO.getList(playerCode);
            if (poList != null && poList.size() > 0) {
                for (int i = 0; i < poList.size(); i++) {
                    PickedTroopsSlot slot = new PickedTroopsSlot();
                    slot.setCode(poList.get(i).getCode());
                    slot.setDataId(poList.get(i).getDataId());
                    slot.setType(poList.get(i).getType());
                    slot.setName(poList.get(i).getName());
                    slot.setQuality(poList.get(i).getQuality());
                    slot.setEntryId(string2ArrayList(poList.get(i).getEntryId()));
                    slot.setValue(string2ArrayList(poList.get(i).getValue()));
                    slot.setIsLock(string2ArrayList(poList.get(i).getIsLock()));
                    slot.setUse(poList.get(i).getUse());
                    slot.setReEntryId(string2ArrayList(poList.get(i).getReEntryId()));
                    slot.setReValue(string2ArrayList(poList.get(i).getReValue()));
                    rMap.put(poList.get(i).getCode(), slot);
                }
            }
        }
        return rMap;
    }


    public static void create(String playerCode, int dataId, long number) throws RedisException {
        commandertally data = DataCenter.getData(dataId, commandertally.class);
        if (data == null) {
            throw new NullPointerException("数据不存在");
        }
        for (int i = 0; i < number; i++) {
            create(data, playerCode);
        }
    }

    //创建兵符
    public static PickedTroopsSlot create(commandertally data, String playerCode) {

        try {
            if (tryLock(playerCode)) {
                RMap<String, PickedTroopsSlot> pickedTroopsSlots = touch(playerCode);
                String code = randomCode();
                while (pickedTroopsSlots.containsKey(code)) {
                    code = randomCode();
                }

                PickedTroopsSlot slot = new PickedTroopsSlot();
                slot.setCode(code);//code
                slot.setDataId(data.getId());//id
                slot.setType(data.getType());//阵营
                slot.setName(data.getName());//名字
                slot.setQuality(data.getQuality());//品质
                slot.setUse(false);//是否在使用

                //获取词条的最高最低区域
                int min = data.getEntryminlevel();
                int max = data.getEntrymaxlevel();

                JSONArray jsonArray = new JSONArray();
                Map<String, commandertallyrandom> allData = DataCenter.getAllData(commandertallyrandom.class);
                for (commandertallyrandom value : allData.values()) {
                    if (value.getEntrylevel() >= min && value.getEntrylevel() <= max) {
                        //对应技能id  以及值
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("id", value.getId());
                        jsonObject.put("value", RandomUtility.nextInt(value.getMin(), value.getMax()));
                        jsonArray.add(jsonObject);
                    }
                }

                int entrynum = data.getEntrynum();//词条数量
                //从map中随机获取词条数量的词条
                ArrayList<Integer> entryIdList = new ArrayList<>();
                ArrayList<Integer> entryValueList = new ArrayList<>();
                ArrayList<Integer> isLock = new ArrayList<>();
                //表中有词条数据才获取
                if (jsonArray.size() > 0) {
                    for (int i = 0; i < entrynum; i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(RandomUtility.nextInt(0, jsonArray.size() - 1));
                        entryIdList.add(jsonObject.getIntValue("id"));
                        entryValueList.add(jsonObject.getIntValue("value"));
                        isLock.add(0);//0 不锁  1 锁住
                    }
                }

                slot.setEntryId(entryIdList);
                slot.setValue(entryValueList);
                slot.setIsLock(isLock);

                //放缓存
                pickedTroopsSlots.put(code, slot);
                return slot;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            unlock(playerCode);
        }
        return null;
    }


    public static boolean set(String playerCode, PickedTroopsSlot slot) {
        try {
            RMap<String, PickedTroopsSlot> touch = touch(playerCode);
            touch.put(slot.getCode(), slot);
            return true;
        } catch (RedisException e) {
            e.printStackTrace();
            return false;
        }
    }

    public static Map<String, PickedTroopsSlot> all(String playerCode) {
        try {
            Map<String, PickedTroopsSlot> slots = touch(playerCode).readAllMap();
            return slots;
        } catch (RedisException e) {
        }
        return new HashMap<>();
    }

    static public PickedTroopsSlot get(String playerCode, String slotCode) {
        try {
            PickedTroopsSlot solt = touch(playerCode).get(slotCode);
            return solt;
        } catch (RedisException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void remove(String playerCode, PickedTroopsSlot slot) {
        try {
            touch(playerCode).remove(slot.getCode());
        } catch (RedisException e) {
        }

    }

    public static void remove(String playerCode, Collection<PickedTroopsSlot> slots) {
        try {
            RMap<String, PickedTroopsSlot> touch = touch(playerCode);
            for (PickedTroopsSlot slot : slots) {
                touch.remove(slot.getCode());
            }
        } catch (RedisException e) {
        }
    }


    private void check() {

    }


    //存储到数据库的方法
    public static void saveToDB(String playerCode) {
        try {
            long updateTime = System.currentTimeMillis();
            //存储
            List<PickedTroopsSlotPo> poList = new ArrayList<>();
            RMap<String, PickedTroopsSlot> rMap = touch(playerCode);
            if (rMap.isExists()) {
                Map<String, PickedTroopsSlot> map = rMap.readAllMap();
                for (String key : map.keySet()) {
                    PickedTroopsSlot value = map.get(key);
                    PickedTroopsSlotPo po = new PickedTroopsSlotPo();
                    po.setPlayerCode(playerCode);
                    po.setCode(value.getCode());
                    po.setDataId(value.getDataId());
                    po.setType(value.getType());
                    po.setName(value.getName());
                    po.setQuality(value.getQuality());
                    po.setEntryId(arrayList2String(value.getEntryId()));
                    po.setValue(arrayList2String(value.getValue()));
                    po.setIsLock(arrayList2String(value.getIsLock()));
                    po.setUse(value.getUse());
                    po.setReEntryId(arrayList2String(value.getReEntryId()));
                    po.setReValue(arrayList2String(value.getReValue()));
                    po.setUpdateTime(updateTime);
                    poList.add(po);
                }
                PickedTroopsSlotDAO.replace(poList);

                PickedTroopsSlotDAO.delete(playerCode, updateTime);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //从redis移走数据的操作
    public static void removeAllFromRedis(String playerCode) {
        try {
            touchBucket(key(playerCode)).delete();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }

    // lock==========================================================================


    static private String lockKey(String playerCode) {
        return String.format("lock:%s", key(playerCode));
    }

    static public boolean lockPickedTroopsSlot(String playerCode) throws InterruptedException {
        return tryLock(lockKey(playerCode));
    }

    static public void unlockPickedTroopsSlot(String playerCode) {
        unlock(lockKey(playerCode));
    }

}
